package com.udima.reglocation;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.udima.reglocation.rest.RestGpsData;
import com.udima.reglocation.rest.RestUserSession;
import com.udima.reglocation.util.AsyncTaskCompleteListener;
import com.udima.reglocation.util.GPSTracker;
import com.udima.reglocation.util.HttpAsyncTask;

/**
 * Pantalla de obtención y registro de datos de localización geográfica del dispositivo.
 * El cliente obtienen mediante el dispositivo GPS del teléfono los datos que permiten
 * identificar la ruta seguida durante un periodo de tiempo y los envia de manera periódica al 
 * servidor para que sean registrados.
 * 
 * La información se envia al servidor en el momento que esta se obtiene y deja de transmitir cuando 
 * se produce un corte en las comunicaciones o envia posiciones nulas si en ese instante no hay una 
 * lectura correcta de la posición en el dispositivo
 * 
 * @author luis
 *
 */

public class SaveTrackActivity extends Activity implements AsyncTaskCompleteListener{
 
	private Activity   activity=this;
    private Button     btnStart;
    private Button     btnStop;
    private TextView   messageTextView;
    private ImageView  imgGpsStatus;
    private GPSTracker gps;
    private Timer      timer;
    
    //Variables para el hilo repetitivo de consulta de GPS que indican el tiempo que tarda en iniciarse el bucle 
    //y el intervalo por defecto entre cada repetición en milisegundos. Este dato se debe sustuir por que esté 
    //configurado para el usuario particular en el onCreate de la clase
    private int delay  = 0;
    private int period = 2000;
    
    //Variables privadas para compartir los datos de las Shared Preferences entre metodos
    private String userSession    = "";
    private String jsonGetUser    = "";
    private String jsonSetGpsData = "";
    private String userId         = "";
    private String appBaseUrl     = "";
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.save_track_activity);
        
    	// Instancia a SharedPreferences
	    SharedPreferences pref = getApplicationContext().getSharedPreferences("com.udima.reglocation", MODE_PRIVATE); 
		
		//Asignación de valores a la clase "restUserSession"
		RestUserSession restUserSession = new RestUserSession();
		restUserSession.setUserId(pref.getString("userId",null));
		restUserSession.setSessionToken(pref.getString("sessionToken",null));
		
		//Serialización de la clase en formato Json dentro de la cadena "userSession"
		Gson gson = new Gson();
		userSession = "\"userSession\":"+gson.toJson(restUserSession)+"";
		jsonGetUser = "{\"userId\":\""+pref.getString("userId",null)+"\"," + userSession + "}";
		
		//Obtención del ID de usuario y la url de envio
		userId     = pref.getString("userId",null);
		appBaseUrl = pref.getString("appBaseUrl",null);
		
		//Consulta al servicio correspondiente para obtener el tiempo de retardo en la consulta GPS 
		//de la configuración del usuario
		//Definición del callback particular al envio de parámetros de consulta del recorrido
		final AsyncTaskCompleteListener callback = new AsyncTaskCompleteListener() {
			@Override
			public void onTaskComplete(String result) {
				Log.i("ServicioRest",result);
				
				try {
					JSONObject json = new JSONObject(result);
					
					//Si la respuesta ha sido satisfactoria, entonces se procesa el resultado
					if(json.getString("responseSuccessful")=="true"){
						JSONObject jsonUser = json.getJSONObject("user");
						
						//Se asigna el valor del periodo de consulta del GPS a la variable correspondiente
						period = Integer.parseInt(jsonUser.getString("fetchGpsLapseTime"));
					}

				} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
				}
			}
			
		};
		
		//Ejecución de la consulta al servicio rest de obtención de recorridos GPS para unas fechas determinadas
		new HttpAsyncTask(activity) {

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                callback.onTaskComplete(result);
            }
        }.execute(pref.getString("appBaseUrl",null) + "/rest/users/",jsonGetUser);    
		

        //Texto e imagen de estado del GPS
        messageTextView = (TextView) findViewById(R.id.gps_status);
        imgGpsStatus    = (ImageView) findViewById(R.id.imgGpsStatus);

        //Botones del formulario
        btnStart        = (Button) findViewById(R.id.btnStart);
        btnStop         = (Button) findViewById(R.id.btnStop);
        
        //Codigo para el boton que inicia el servicio
        //Se borran todos los datos y se crean timer y servicio para escuchar al GPS
        btnStart.setOnClickListener(new View.OnClickListener() {
        	 
            public void onClick(View view) {
            	
            	//Creación del nuevo temporizador
            	timer = new Timer();

        		// Creacion del objeto clase del GPSTracker
            	gps = new GPSTracker(SaveTrackActivity.this);
                
                // Comprobación de que el GPS está habilitado     
                if(gps.canGetLocation()){
                	
                	//Cambio en el mensaje y la imagen de estado del servicio
                	messageTextView.setText("Servicio iniciado");
                	imgGpsStatus.setImageResource(getResources().getIdentifier("gps_searching", "drawable", getPackageName()));

                	//Temporizador para iterar el grabado de datos lo que indica la variable period
            		timer.scheduleAtFixedRate(new TimerTask()
            		{
            			public void run(){
            				//
            		        SaveTrackActivity.this.runOnUiThread(new Runnable() {
            		            @Override
            		            public void run() {
            		            	sendLocation();
            		            }
            		        });
            				
            			}
            		}, delay, period);
                }else{
                    // No se puede obtener la localización
                    // GPS o red no habilitada
                    // Se pregunta al usuario por la configuración del GPS o de la red
                    gps.showSettingsAlert();
                }

            }
        });
        
        //Codigo para el boton de parada del servicio
        //Se elimina el timer y se detiene la recepcion de datos via GPS
        btnStop.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
            	
            	//Destrucción del temporizador y parada del servicio GPS
				timer.cancel();
				gps.stopUsingGPS();
				
				//Cambio en el mensaje y la imagen de estado del servicio
                messageTextView.setText("Servicio detenido");
                imgGpsStatus.setImageResource(getResources().getIdentifier("gps_disconnected", "drawable", getPackageName()));
            }
        });
    }       	
    
    @SuppressLint("SimpleDateFormat")
	public void sendLocation() {

    	//Obtención de la posición actual del GPS
		double latitude  = gps.getLatitude();
        double longitude = gps.getLongitude();
        
    	//Cambio en el mensaje y la imagen de estado del servicio
    	messageTextView.setText("Recibiendo datos\n lat: " + String.valueOf(latitude) + "\n lon: " + String.valueOf(longitude));
    	imgGpsStatus.setImageResource(getResources().getIdentifier("gps_receiving", "drawable", getPackageName()));
		
		//Asignación de valores a la clase "restGpsData"
		RestGpsData restGpsDta = new RestGpsData();
		restGpsDta.setUserId(userId);
		restGpsDta.setFetchTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()));
		restGpsDta.setLat(String.valueOf(latitude));
		restGpsDta.setLon(String.valueOf(longitude));
		
		//Creación y serialización de la cadena gpsData con los datos de envio del GPS en formato json
		Gson gson      = new Gson();
		String gpsData = "\"gpsData\":["+gson.toJson(restGpsDta)+"]";
		jsonSetGpsData = "{" + userSession + "," + gpsData + "}";
		
		//Ejecución del envio de datos del GPS al servidor sin callback
     	new HttpAsyncTask(activity).execute(appBaseUrl + "/rest/gps/store/", jsonSetGpsData);
	}

	@Override
	public void onTaskComplete(String result) {
		
	}
 
}
